package chatBot.controller;

import chatBot.common.Result;
import chatBot.dto.UserDto;
import chatBot.entity.User;
import chatBot.service.UserService;
import chatBot.utils.EmailUtil;
import chatBot.utils.FormatChecker;
import cn.hutool.core.util.RandomUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import static chatBot.constans.RedisConstant.USER_CODE_KEY;
import static chatBot.constans.RedisConstant.USER_CODE_TTL;


@Slf4j
@RestController
@Api(tags = "用户功能")
@RequestMapping("/gpt")
public class UserController {
    @Autowired
    private EmailUtil emailUtil;
    @Resource
    StringRedisTemplate stringRedisTemplate;


    @Resource
    UserService userService;

    private static final Integer MIN_PSW_LEN = 6;

    //创建一个线程
    private static final ExecutorService SECKILL_ORDER_EXECUTOR = Executors.newSingleThreadExecutor();

    /**
     * 生成邮箱验证码
     *
     * @param
     * @return
     */
    @ApiOperation("发送验证码")
    @GetMapping("/sendMsg")
    public Result<String> sendMsg(String userEmail) {

        if (StringUtils.isNotEmpty(userEmail)) {
            //生成4位数随机验证码
            String numbers = RandomUtil.randomNumbers(4);
            log.info(userEmail + "," + numbers);
            //开启一个独立的线程去发送邮箱，这样就不会导致签到页面响应超时
            SECKILL_ORDER_EXECUTOR.submit(() -> {
                try {
                    String subject = "登录验证码";
                    emailUtil.sendMessage(userEmail, subject, numbers);
                } catch (Exception e) {
                    throw new RuntimeException();
                }
            });

            // code存入Redis
            stringRedisTemplate.opsForValue().set(USER_CODE_KEY + userEmail, numbers, USER_CODE_TTL, TimeUnit.MINUTES);

            return Result.success(numbers);
        }
        return Result.fail(400, "验证码发送失败！");
    }


    @ApiOperation("邮箱注册功能")
    @PostMapping("/register")
    public Result<Object> register(@RequestBody Map<String, Object> map) {
        String userEmail = (String) map.get("email");
        String code = (String) map.get("captcha");
        String password = (String) map.get("password");

        // 校验邮箱号与验证码格式，以及是否为空
        if (!FormatChecker.isValidEmail(userEmail)) {
            return Result.fail(400, "邮箱格式错误");
        }
        if (!FormatChecker.isCode(code)) {
            return Result.fail(400, "验证码格式错误");
        }
        if (password == null || password.length() < MIN_PSW_LEN) {
            return Result.fail(400, "密码为空或密码长度过短");
        }

        // 调用userService
        Map<String, Object> tokenAndUserMap = userService.register(userEmail, code, password);
        if (tokenAndUserMap == null) {
            return Result.fail(400, "验证码输入错误，或用户已注册");
        }
        return Result.success(tokenAndUserMap);
    }

    @ApiOperation("邮箱登录功能")
    @PostMapping("/login")
    public Result<Object> login(@RequestBody Map<String, Object> map) {
        String userEmail = (String) map.get("email");
        String code = (String) map.get("captcha");

        String password = (String) map.get("password");
        log.info("password" + password);


        if (!FormatChecker.isValidEmail(userEmail)) {
            return Result.fail(400, "邮箱号格式错误");
        }

        // 验证码非空时，校验验证码格式
        if (code != null && !FormatChecker.isCode(code)) {
            // 验证码格式错误
            return Result.fail(400, "选择使用验证码登录，但验证码格式错误");
        }

        // 返回用户信息map，key为"user"和"token"
        Map<String, Object> tokenAndUserMap = userService.login(userEmail, code, password);
        if (tokenAndUserMap == null) {
            // 返回null说明登录失败啦
            return Result.fail(400, "登录失败");
        }
        log.info("用户"+tokenAndUserMap.get("user")+"登录成功");
        return Result.success(tokenAndUserMap);
    }

    @ApiOperation("退出功能")
    @GetMapping("/logout")
    public Result<Object> logout() {
        userService.logout();
        return Result.success("用户退出登录");
    }

    @ApiOperation("重命名功能")
    @PutMapping("/userInfo")
    public Result<Object> updateUserInfo(@RequestBody User user) {
        // 获取SecurityContextHolder中的用户id
        UsernamePasswordAuthenticationToken authenticationToken =
                (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        Long userId = (Long) authenticationToken.getPrincipal();

        if (!userId.equals(user.getUserId())) {
            return Result.fail("只能更改自己的用户信息哦！");
        }

        return Result.success(userService.updateUserInfo(user));
    }

    @ApiOperation(value = "获取用户信息", notes = "通过用户 ID 获取用户信息")
    @GetMapping("/getUserInfo")
    public Result<UserDto> getUserInfo(@RequestParam("userId") Long userId) {
        UserDto userDto = userService.getUserInfo(userId);
        return Result.success(userDto);
    }


}
